<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型模式（Prototype Pattern）</title>
    <!-- 
  原型模式（Prototype Pattern）是一种创建型设计模式，它允许通过复制现有的对象来创建新对象，而不是通过实例化新对象。原型模式的主要目的是通过克隆（复制）一个对象来避免昂贵的创建过程，尤其是在对象的创建过程比较复杂或者资源消耗较大的情况下。

  ### 原型模式的主要组成部分

  1. **原型接口（Prototype）**：定义一个克隆方法，用于克隆自身的对象。
  2. **具体原型（Concrete Prototype）**：实现原型接口，提供具体的克隆方法。
  3. **客户端（Client）**：使用原型来创建新对象。

  ### 原型模式的优点

  1. **避免类的依赖**：通过克隆现有对象来创建新对象，减少了类的依赖。
  2. **提高性能**：在某些情况下，克隆对象比创建新对象更高效，特别是当对象的创建过程复杂时。
  3. **动态配置**：可以在运行时动态地改变对象的状态，而不需要依赖具体的类。

  ### 原型模式的缺点

  1. **复杂的克隆过程**：如果对象中包含复杂的引用类型，克隆过程可能会变得复杂，尤其是需要深拷贝时。
  2. **增加内存开销**：克隆对象可能导致内存的额外开销，尤其是在大量对象被克隆的情况下。

  ### 示例代码

  以下是一个使用原型模式的简单示例，展示如何通过克隆对象来创建新对象。

  #### 1. 原型接口（Prototype）
  ```javascript
  class Prototype {
      clone() {
          throw new Error("This method must be implemented.");
      }
  }
  ```

  #### 2. 具体原型（Concrete Prototype）
  ```javascript
  class ConcretePrototype extends Prototype {
      constructor(name) {
          super();
          this.name = name;
      }

      clone() {
          return new ConcretePrototype(this.name);
      }
  }
  ```

  #### 3. 使用示例
  ```javascript
  const original = new ConcretePrototype("原型对象");
  const clone = original.clone();

  console.log(clone.name); // 输出: "原型对象"
  console.log(clone === original); // 输出: false，说明是不同的对象
  ```

  ### 总结

  原型模式是一种有效的设计模式，适用于需要频繁创建相似对象的场景。通过克隆现有对象，原型模式能够提高对象创建的效率，并减少对类的依赖。在设计系统时，合理运用原型模式可以简化对象的创建过程，尤其是在对象创建复杂或资源消耗较大的情况下。
  --></head>

  <body>
    <script>
      // 原型模式是一种创建型设计模式，它允许通过复制现有对象来创建新对象，而不是通过创建类的新实例。原型模式的主要优点包括：
      // 1. **减少重复代码**：通过克隆现有对象，可以避免重复编写相同的代码。
      // 2. **提高性能**：创建新对象时，原型模式可以避免重复执行构造函数，从而提高性能。
      // 3. **灵活的对象配置**：可以在运行时动态地改变对象的状态，而不需要依赖具体的类。

      class Prototype {
        clone() {
          throw new Error("This method must be implemented.");
        }
      }

      class ConcretePrototype extends Prototype {
        constructor(name) {
          super();
          this.name = name;
        }

        clone() {
          return new ConcretePrototype(this.name);
        }
      }

      const original = new ConcretePrototype("原型对象");
      const clone = original.clone();

      console.log(clone.name); // 输出: "原型对象"
      console.log(clone === original); // 输出: false，说明是不同的对象
    </script>
  </body>
</html>
